//== SAGITTARIUS ============================================================================

//== FILEDOC =========================================================================

/** @file dfa.h
  * @brief Generates a deterministic finite automaton from a RE or lexvec
  */

//== BEGINNING OF CODE ===============================================================

#ifndef __SAGUTTARUIS__DFA__H_
#define __SAGUTTARUIS__DFA__H_

//== INCLUDES ========================================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/lexer/lAST.h"
#include "sagittarius/re/reDC.h"
#include "sagittarius/lexer/lexvec.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    DFA_STATE_START,
    DFA_STATE_INTERN,
    DFA_STATE_ACCEPT,
    DFA_STATE_REJECT
} DFA_StateType;

typedef struct {
    //this is why Linus wanted free to take a void ptr
    //the whole time we hold cs, we never modify it, but 
    //we do need to free it when done
//#if LX_USE_POOLALLOC
    RE_CharSet* cs;
//#else
    //const RE_CharSet* cs;
//#endif
    uint32 s; //state #
} dfa_outTran;

typedef struct __dfa_outTranLink {
    dfa_outTran* cur;
    struct __dfa_outTranLink* next;
} dfa_outTranLink;

typedef struct {
    lexvec* v;
    dfa_outTranLink *tbeg, *tend;
    ///An example string that can be used to derive this state
    LexBuf dstr;
    ///Length of @ref dstr;
    //uint32 dstrlen;
} dfaState;

typedef struct {
    uint32 n; //# of states
    uint32 cap;
    dfaState** s; //states
} dfarep;

/** @brief Make a DFA from a single RE
 */
//dfarep* lex_makeDFAsingle(lASTNode* e);

/** @brief Make a DFA from a lexvec
 */
dfarep* lex_makeDFAvec(lexvec* v);

void dfa_destroy(dfarep* dfa);

void lex_dumpTransitions(int fd, const dfaState* s);
void lex_dumpDFAState(int fd, const dfaState* s);
void lex_dumpDFA(int fd, dfarep* dfa);

#ifdef __cplusplus
}//extern "C"
#endif

#endif
